#pragma once
#include<vector>
#include"Sem.hpp"
#include"Mutex.hpp"
static const int gcap=5;
using namespace SemModule;
using namespace MutexMudole;
template <class T>
class RingQueue {
    private:
       std::vector<T>_rq;
        int _cap;
        Sem _blank_sem;//表示空的资源
        Sem _data_sem;//表示数据的资源
        int _p_step;//消费者位置
        int _c_step;//生产者位置
        Mutex _p_mutex;
        Mutex _c_mutex;
    public:
       RingQueue(int size = gcap)
    : _rq(size),
      _cap(size),
      _blank_sem(size),   // 空位一开始是满的
      _data_sem(0),       // 数据一开始是空的
      _p_step(0),
      _c_step(0) {}

void Enqueue(const T& in) {
    _blank_sem.P();          // 申请空位
    LockGuard lock(_p_mutex);
    _rq[_p_step] = in;
    _p_step = (_p_step + 1) % _cap;
    _data_sem.V();           // 释放数据
}

void Pop(T& out) {
    _data_sem.P();           // 申请数据
    LockGuard lock(_c_mutex);
    out = _rq[_c_step];
    _c_step = (_c_step + 1) % _cap;
    _blank_sem.V();          // 释放空位
}

};